using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.IO;
using System.Net.Mail;
using System.Reflection;
using System.Web;
using Edge.Common.ComponentModel;
using Edge.Common.ControlFlow;
using Edge.Common.Services;
using Edge.Common.TextTemplates;
using Edge.Common.TextTemplates.Exceptions;
using Edge.Common.TextTemplates.Impl.ASPNET;
using Edge.Common.Utils;
using log4net;

namespace Edge.Common.Mail
{
    public class SendMailByTemplate
    {
        private static readonly ILog log = LogManager.GetLogger(MethodInfo.GetCurrentMethod().DeclaringType);

        private string subject;
        private string pathToBody;
        private string mailFrom;
        private string to;
        List<string> mailCc;
        private IDictionary<string, object> parameters;

        public SendMailByTemplate(string subject, string pathToBody, string mailFrom, string to, List<string> mailTo, IDictionary<string, object> parameters)
        {
            Subject = subject;
            PathToBody = pathToBody;
            MailFrom = mailFrom;
            To = to;
            MailCc = mailTo;
            Parameters = parameters;
        }

        public IDictionary<string, object> Parameters
        {
            get { return parameters; }
            set { parameters = value; }
        }

        public string To
        {
            get { return to; }
            set { to = value; }
        }

        public List<string> MailCc
        {
            get { return mailCc; }
            set
            {
                if (!CollectionsUtils.IsEmpty<string>(value))
                {
                    if (mailCc != null)
                        mailCc.Clear();
                    else
                        mailCc = new List<string>();

                    if (value.Count > 0)
                    {
                        value.Sort();
                        mailCc.Add(value[0]);
                        foreach (string ml in value)
                            if (mailCc[mailCc.Count - 1] != ml)
                                mailCc.Add(ml);
                    }
                }
                else
                    mailCc = null;
            }
        }

        public string Subject
        {
            get { return subject; }
            set { subject = value; }
        }

        public string PathToBody
        {
            get { return pathToBody; }
            set { pathToBody = value; }
        }

        public string MailFrom
        {
            get { return mailFrom; }
            set { mailFrom = value; }
        }

        protected ITextEngine GetTextEngine()
        {
            string templatesPath = GetTemplatesPath();
            log.InfoFormat("TemplatesPath: {0}.", templatesPath);

            ITextEngine textEngine = TextEngineFactory.Instance().GetEngine(templatesPath, false);
            Assert.CheckNotNull(textEngine);
            return textEngine;
        }

        private string GetTemplatesPath()
        {
            string templatesPath = AppDomain.CurrentDomain.RelativeSearchPath;
            Assert.CheckNotNull(templatesPath);
            if (!templatesPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
                templatesPath += Path.DirectorySeparatorChar.ToString();

            templatesPath += "TextTemplates";
            return templatesPath;
        }

        public bool Send()
        {
            string body = string.Empty;
            string strBeginLog = string.Format("Subject: {0}; From {1}; To: {2}; Cc: {3}", Subject,
               MailFrom, To, MailUtils.ListCcToString(MailCc));

            try
            {
                AttachmentStore attachmentsStore = new AttachmentStore();

                body = string.Empty;
                try
                {
                    if (!StringUtils.IsBlankOrNull(pathToBody))
                    {
//                        SimpleServiceProvider provider = new SimpleServiceProvider();
//                        provider.AddService(typeof(IAttachmentStore), attachmentsStore);
//
                        body = Render();

                        
                    }
                }
                catch (Exception error)
                {
                    body += "<br /> Error at preparing template '" + pathToBody + "'. Please inform Administrator.";
//                    log.InfoFormat(strBeginLog + "; Error: {0}.", "Error at preparing template '" + pathToBody + "'; " + error.Message);
//                    if (error.InnerException != null)
//                    {
//                        log.InfoFormat("Inner Error Message: {0}", error.InnerException.Message);
//                        log.InfoFormat("Inner Error Source: {0}", error.InnerException.Source);
//                        log.InfoFormat("Inner Error StackTrace: {0}", error.InnerException.StackTrace);
//                        log.InfoFormat("Inner Error HelpLink: {0}", error.InnerException.HelpLink);
//                    }
                    body += "<br/>"+error.Message;
                    if (error.InnerException != null)
                    {
                        body += "<br/>"+"Inner Error Message: " + error.InnerException.Message;
                        body += "<br/>"+"Inner Error Source: " + error.InnerException.Source;
                        body += "<br/>"+"Inner Error StackTrace: " + error.InnerException.StackTrace;
                        body += "<br/>"+"Inner Error HelpLink:  " + error.InnerException.HelpLink;
                    }
                }

                MailMessage mm = new MailMessage();
                if (MailUtils.PrepareMailMessage(Subject, To, MailCc, MailFrom, body, attachmentsStore, ref mm))
                {
                    Locator.GetService<ISendMailService>().Send(mm);
                    log.Info(strBeginLog + ". EMail message was successfully send.");
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                log.InfoFormat(strBeginLog + "; Error: {0}.", ex);
                return false;
            }
            return true;

            //            if ((!CollectionsUtils.IsEmpty<string>(MailCc)) || (!StringUtils.IsBlankOrNull(this.To)))
            //            {
            //                try
            //                {
            //                    string body = string.Empty;
            //
            //                    AttachmentStore attachmentsStore = new AttachmentStore();
            //
            //                    if (!StringUtils.IsBlankOrNull(pathToBody))
            //                    {
            //                        SimpleServiceProvider provider = new SimpleServiceProvider();
            //                        provider.AddService(typeof (IAttachmentStore), attachmentsStore);
            //
            //                        body = GetTextEngine().Render(pathToBody, Parameters, provider);
            //                    }
            //                    else
            //                        body = "";
            //
            //
            //                    MailMessage mm = new MailMessage();
            //
            //                    mm.IsBodyHtml = true;
            //
            //                    string strTo = this.To;
            //                    if (!StringUtils.IsBlankOrNull(strTo))
            //                    {
            //                        if (strTo.IndexOf("@") > 0)
            //                            mm.To.Add(strTo);
            //                        else
            //                            log.Fatal("The specified string 'EMail To' ('" + strTo + "') is not in the form required for an e-mail address");
            //                    }
            //
            //                    if (!CollectionsUtils.IsEmpty<string>(MailCc))
            //                        foreach (string str in this.MailCc)
            //                        {
            //                            if (!StringUtils.IsBlankOrNull(str))
            //                                if (str.IndexOf("@") > 0)
            //                                    mm.CC.Add(str);
            //                                else
            //                                    log.Fatal("The specified string '" + str + "' is not in the form required for an e-mail address");
            //                        }
            //                    if ((CollectionsUtils.IsEmpty<MailAddress>(mm.CC)) && (StringUtils.IsBlankOrNull(this.To)))
            //                        return false;
            //
            //                    if (!StringUtils.IsBlankOrNull(MailFrom))
            //                        mm.From = new MailAddress(MailFrom);
            //
            //                    mm.Body = body;
            //                    mm.Subject = Subject != null ? Subject.Replace('\r', ' ').Replace('\n', ' ') : "";
            //
            //                    foreach (string fileName in attachmentsStore.Files)
            //                    {
            //                        try
            //                        {
            //                            string flName = fileName;
            //                            if (fileName[0] == '~')
            //                            {
            //                                flName = GetTemplatesPath() +
            //                                         Path.DirectorySeparatorChar.ToString() + fileName.Substring(2);
            //                            }
            //                            mm.Attachments.Add(new Attachment(flName));
            //                        }
            //                        catch (Exception ex)
            //                        {
            //                        }
            //                    }
            //
            //                    Locator.GetService<ISendMailService>().Send(mm);
            //                    return true;
            //                }
            //                catch (Exception ex)
            //                {
            //                    return false;
            //                }
            //            }
            //            return false;
        }
        public string Render()
        {
            string s = File.ReadAllText(pathToBody);
            
            if (Parameters == null)
                return StringUtils.TextileToHtml(s);


            foreach (KeyValuePair<string, object> pair in Parameters)
            {
                try
                {
                    if (s.Contains("{" + pair.Key + "}"))
                        s = s.Replace("{" + pair.Key + "}",pair.Value.ToString());
                }
                catch (Exception ex)
                {
                    throw new PrepareTemplateException("Error at binding parametr " + pair.Key, ex);
                }
            }
            return StringUtils.TextileToHtml(s);
        }

       
    }
}

